const baseUrl = 'http://nv582w.natappfree.cc'; // 请确保链接是有效的
// const baseUrl = 'http://192.168.96.118:3333'; // 本地测试地址

let canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const cellSize = 20; // 每个格子的大小
const gridSize = canvas.width / cellSize; // 网格大小

let snake = [{ x: 10, y: 10 }]; // 蛇的初始位置
let direction = { x: 1, y: 0 }; // 初始方向向右
let food = { x: 15, y: 15 }; // 食物的初始位置
let gameRunning = false; // 游戏是否运行
let gameSpeed = 100; // 游戏速度（毫秒）
let score = 0; // 得分
let difficulty = 0; // 游戏难度
let difficultyInterval; // 难度增加的定时器

// 获取开始按钮和难度选择器
const startButton = document.getElementById('startButton');
const difficultySelect = document.getElementById('difficulty');
const leaderboardList = document.getElementById('leaderboardList');

// 排行榜数据
let leaderboard = [];

// 加载排行榜数据
updateLeaderboard();

// 设置难度
function setDifficulty() {
  const selectedDifficulty = parseInt(difficultySelect.value);
  gameSpeed = 250 - selectedDifficulty * 10; // 根据难度调整速度
}

// 开始游戏
startButton.addEventListener('click', () => {
  setDifficulty();
  snake = [{ x: 10, y: 10 }];
  direction = { x: 1, y: 0 };
  food = generateFood();
  score = 0; // 重置得分
  difficulty = 0; // 重置难度
  gameRunning = true;
  clearInterval(difficultyInterval); // 清除之前的定时器
  difficultyInterval = setInterval(increaseDifficulty, 10000); // 每10秒增加难度
  update();
});

// 绘制蛇和食物
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 绘制棋盘格线
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
  ctx.lineWidth = 1;
  for (let x = 0; x < canvas.width; x += cellSize) {
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineTo(x, canvas.height);
    ctx.stroke();
  }
  for (let y = 0; y < canvas.height; y += cellSize) {
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(canvas.width, y);
    ctx.stroke();
  }

  // 绘制蛇
  snake.forEach((segment, index) => {
    const gradient = ctx.createLinearGradient(
      segment.x * cellSize,
      segment.y * cellSize,
      (segment.x + 1) * cellSize,
      (segment.y + 1) * cellSize,
    );
    gradient.addColorStop(
      0,
      index === 0 ? '#FF5733' : `hsl(${index * 10}, 100%, 50%)`,
    );
    gradient.addColorStop(1, 'black');

    ctx.shadowBlur = 5;
    ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
    ctx.fillStyle = gradient;
    ctx.fillRect(
      segment.x * cellSize,
      segment.y * cellSize,
      cellSize,
      cellSize,
    );
    ctx.shadowBlur = 0;
  });

  // 绘制食物
  ctx.fillStyle = '#FFFF00';
  ctx.shadowBlur = 5;
  ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
  ctx.beginPath();
  ctx.arc(
    food.x * cellSize + cellSize / 2,
    food.y * cellSize + cellSize / 2,
    cellSize / 2,
    0,
    Math.PI * 2,
  );
  ctx.fill();
  ctx.shadowBlur = 0;
}

// 更新游戏状态
function update() {
  if (!gameRunning) return;

  const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };

  if (
    head.x < 0 ||
    head.x >= gridSize ||
    head.y < 0 ||
    head.y >= gridSize ||
    snake.some((segment) => segment.x === head.x && segment.y === head.y)
  ) {
    gameRunning = false;
    clearInterval(difficultyInterval); // 游戏结束时清除难度增加的定时器
    endGame();
    return;
  }

  snake.unshift(head);

  if (head.x === food.x && head.y === food.y) {
    score += 10;
    food = generateFood();
  } else {
    snake.pop();
  }

  draw();

  setTimeout(update, gameSpeed);
}

// 生成食物
function generateFood() {
  let newFood;
  do {
    newFood = {
      x: Math.floor(Math.random() * gridSize),
      y: Math.floor(Math.random() * gridSize),
    };
  } while (
    snake.some((segment) => segment.x === newFood.x && segment.y === newFood.y)
  );
  return newFood;
}

// 游戏结束
async function endGame() {
  if (leaderboard.length < 10 || score > leaderboard[9].score) {
    showPrompt('恭喜你进入前十！请输入你的昵称：', async (nickname) => {
      if (nickname) {
        await fetch(`${baseUrl}/snake-score`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ username: nickname, score: score }),
        })
          .then((response) => response.json())
          .then((data) => {
            console.log('Success:endGame', data);
          })
          .catch((error) => {
            console.error('Error:endGame', error);
          });

        updateLeaderboard();
      }
    });
  } else {
    showModal('游戏结束！你的得分：' + score);
  }
}

// 更新排行榜
async function updateLeaderboard() {
  await fetch(`${baseUrl}/snake-score/leaderboard`)
    .then((response) => response.json())
    .then((data) => {
      leaderboard = data;
      console.log('Success:', data);
    })
    .catch((error) => {
      console.error('Error:', error);
      document.getElementById('result').innerText = 'Failed to fetch data';
    });

  leaderboardList.innerHTML = '';
  leaderboard.forEach((entry, index) => {
    const li = document.createElement('li');
    li.textContent = `${index + 1}. ${entry.username} - ${entry.score}`;
    leaderboardList.appendChild(li);
  });
}

// 监听键盘事件
document.addEventListener('keydown', (event) => {
  switch (event.key) {
    case 'ArrowUp':
      if (direction.y === 1) break;
      direction = { x: 0, y: -1 };
      break;
    case 'ArrowDown':
      if (direction.y === -1) break;
      direction = { x: 0, y: 1 };
      break;
    case 'ArrowLeft':
      if (direction.x === 1) break;
      direction = { x: -1, y: 0 };
      break;
    case 'ArrowRight':
      if (direction.x === -1) break;
      direction = { x: 1, y: 0 };
      break;
  }
});

// 监听触摸事件（手机端）
let startX, startY;

canvas.addEventListener('touchstart', (event) => {
  const touch = event.touches[0];
  startX = touch.clientX;
  startY = touch.clientY;
  event.preventDefault();
});

canvas.addEventListener('touchend', (event) => {
  const touch = event.changedTouches[0];
  const endX = touch.clientX;
  const endY = touch.clientY;

  const deltaX = endX - startX;
  const deltaY = endY - startY;

  if (Math.abs(deltaX) > Math.abs(deltaY)) {
    // 水平滑动
    if (deltaX > 0 && direction.x !== -1) {
      direction = { x: 1, y: 0 }; // 向右
    } else if (deltaX < 0 && direction.x !== 1) {
      direction = { x: -1, y: 0 }; // 向左
    }
  } else {
    // 垂直滑动
    if (deltaY > 0 && direction.y !== -1) {
      direction = { x: 0, y: 1 }; // 向下
    } else if (deltaY < 0 && direction.y !== 1) {
      direction = { x: 0, y: -1 }; // 向上
    }
  }
  event.preventDefault();
});

// 初始绘制蛇和食物
draw();

// 自定义模态框
const modal = document.createElement('div');
modal.id = 'gameModal';
modal.style.position = 'fixed';
modal.style.top = '0';
modal.style.left = '0';
modal.style.width = '100%';
modal.style.height = '100%';
modal.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
modal.style.display = 'flex';
modal.style.justifyContent = 'center';
modal.style.alignItems = 'center';
modal.style.zIndex = '1000';
modal.style.display = 'none';

const modalContent = document.createElement('div');
modalContent.style.backgroundColor = 'white';
modalContent.style.padding = '20px';
modalContent.style.borderRadius = '10px';
modalContent.style.textAlign = 'center';

modal.appendChild(modalContent);
document.body.appendChild(modal);

// 显示模态框
function showModal(message, callback) {
  modalContent.innerHTML = `
    <p>${message}</p>
    <button id="modalButton" style="padding: 10px 20px; margin-top: 10px;">确定</button>
  `;
  const modalButton = document.getElementById('modalButton');
  modalButton.addEventListener('click', () => {
    modal.style.display = 'none';
    if (callback) callback();
  });
  modal.style.display = 'flex';
}

// 显示输入框模态框
function showPrompt(message, callback) {
  modalContent.innerHTML = `
    <p>${message}</p>
    <input type="text" id="modalInput" placeholder="请输入昵称" style="padding: 10px; margin-top: 10px; width: 80%;"/>
    <button id="modalButton" style="padding: 10px 20px; margin-top: 10px;">确定</button>
  `;
  const modalButton = document.getElementById('modalButton');
  modalButton.addEventListener('click', () => {
    const nickname = document.getElementById('modalInput').value;
    modal.style.display = 'none';
    if (callback) callback(nickname);
  });
  modal.style.display = 'flex';
}

// 每10秒增加难度
function increaseDifficulty() {
  difficulty += 1;
  gameSpeed -= 10; // 每增加1难度，速度加快10毫秒
  console.log(`难度增加，当前难度：${difficulty}，游戏速度：${gameSpeed}`);
}
